const vscode = require('vscode');
const fs = require('fs');
const path = require('path');
const ini = require('ini');
const iconv = require('iconv-lite');
const crypto = require('crypto');
class Configs {
    static name = 'mir-script-config';
    rootPath = "";
    serverNames = {
        'DBServer': "数据库服务",
        'LoginSrv': "账号登录服务",
        'LogServer': "日志服务",
        'M2Server': "M2主服务",
        'RunGate': "运行网关",
        'SelGate': "角色网关",
        'LoginGate': "登录网关"
    }
    constructor() {
        this.loadRootConfig();
        this.initServerFile();
    }

    loadIni(filename, encoding = "gb2312") {
        const buffer = fs.readFileSync(filename)
        return ini.parse(iconv.decode(buffer, encoding))
    }
    saveIni(filename, obj, encoding = "gb2312") {
        const encoded = iconv.encode(ini.stringify(obj), encoding)
        fs.writeFileSync(filename, encoded, { encoding: 'binary' })
    }
    loadRootConfig() {
        this.config = vscode.workspace.getConfiguration(Configs.name);
        this.rootPath = this.config.get("RootPath");
        if (!this.rootPath || fs.existsSync(this.rootPath) === false) {
            vscode.window.showErrorMessage('请先设置服务器根目录');
            return
        }
        const configFilename = path.join(this.rootPath, 'Config.ini');
        if (fs.existsSync(configFilename) === false) {
            vscode.window.showErrorMessage(`${configFilename}配置文件不存在!`);
            return
        }
        this.rootConfig = this.loadIni(configFilename);
    }

    makeHash(str) {
        return crypto.createHash('md5').update(str).digest('hex');
    }
    initServerFile() {
        /** @type {ServerFile[]} */
        this.serverFiles = []
        for (const name in this.serverNames) {
            if (!Object.prototype.hasOwnProperty.call(this.serverNames, name)) {
                continue
            }
            const filename = this.config.get(`${name}File`);
            const hash = this.makeHash(`server_${name}`)
            const file = { filename, name, title: this.serverNames[name], dir: "", basename: '', number: 1, items: [], hash }
            if (name === "RunGate") {
                file.number = parseInt(this.rootConfig?.RunGate?.Count || 1)
                for (let index = 1; index <= file.number; index++) {
                    const port = this.rootConfig?.RunGate?.[`GatePort${index}`]
                    const hash = this.makeHash(`server_${name}_${index}`)
                    file.items.push({ label: `网关${index}`, description: port, hash, port: parseInt(port) })
                }
            }
            if (fs.existsSync(filename)) {
                file.dir = path.dirname(filename)
                file.basename = path.basename(filename)
            }
            this.serverFiles.push(file)
        }

        this.config.get("OtherServerFile").forEach(line => {
            const arr = line.split("|")
            const filename = arr[0]?.trim()
            if (!filename) {
                return
            }
            const file = { filename, title: arr[1]?.trim(), name: arr[2]?.trim(), dir: '', basename: '', number: arr[3] || 1 }
            if (fs.existsSync(filename)) {
                const pathinfo = path.parse(filename)
                file.dir = pathinfo.dir
                file.basename = pathinfo.base
                if (!file.name) {
                    file.name = pathinfo.name
                }
                if (!file.title) {
                    file.title = pathinfo.name
                }
            }
            file.hash = this.makeHash(`other_${file.name}_${file.filename}`)
            if (file.number > 1) {
                for (let index = 1; index <= file.number; index++) {
                    const hash = this.makeHash(`other_${file.name}_${file.filename}_${index}`)
                    file.items.push({ label: file.title, description: file.name, hash })
                }
            }
            this.serverFiles.push(file)
        });

    }
}

module.exports = { Configs };